
<html><head>
<title>flibs/datastructures - flibs</title>
<style type="text/css"><!--
    HTML {
	background: 	#FFFFFF;
	color: 		black;
    }
    BODY {
	background: 	#FFFFFF;
	color:	 	black;
    }
    DIV.doctools {
	margin-left:	10%;
	margin-right:	10%;
    }
    DIV.doctools H1,DIV.doctools H2 {
	margin-left:	-5%;
    }
    H1, H2, H3, H4 {
	margin-top: 	1em;
	font-family:	sans-serif;
	font-size:	large;
	color:		#005A9C;
	background: 	transparent;
	text-align:		left;
    }
    H1.title {
	text-align: center;
    }
    UL,OL {
	margin-right: 0em;
	margin-top: 3pt;
	margin-bottom: 3pt;
    }
    UL LI {
	list-style: disc;
    }
    OL LI {
	list-style: decimal;
    }
    DT {
	padding-top: 	1ex;
    }
    UL.toc,UL.toc UL, UL.toc UL UL {
	font:		normal 12pt/14pt sans-serif;
	list-style:	none;
    }
    LI.section, LI.subsection {
	list-style: 	none;
	margin-left: 	0em;
	text-indent:	0em;
	padding: 	0em;
    }
    PRE {
	display: 	block;
	font-family:	monospace;
	white-space:	pre;
	margin:		0%;
	padding-top:	0.5ex;
	padding-bottom:	0.5ex;
	padding-left:	1ex;
	padding-right:	1ex;
	width:		100%;
    }
    PRE.example {
	color: 		black;
	background: 	#f5dcb3;
	border:		1px solid black;
    }
    UL.requirements LI, UL.syntax LI {
	list-style: 	none;
	margin-left: 	0em;
	text-indent:	0em;
	padding:	0em;
    }
    DIV.synopsis {
	color: 		black;
	background: 	#80ffff;
	border:		1px solid black;
	font-family:	serif;
	margin-top: 	1em;
	margin-bottom: 	1em;
    }
    UL.syntax {
	margin-top: 	1em;
	border-top:	1px solid black;
    }
    UL.requirements {
	margin-bottom: 	1em;
	border-bottom:	1px solid black;
    }
--></style>
</head>
<! -- Generated from file 'datastructures/sets.man' by tcllib/doctools with format 'html'
   -->
<! -- Copyright &copy; 2006 Arjen Markus &lt;arjenmarkus@sourceforge.net&gt;
   -->
<! -- CVS: $Id: sets.html,v 1.2 2013/05/13 08:03:15 knystrom Exp $ flibs/datastructures.n
   -->
<body><div class="doctools">
<h1 class="title">flibs/datastructures(n) 1.0  &quot;flibs&quot;</h1>
<div id="name" class="section"><h2><a name="name">Name</a></h2>
<p>flibs/datastructures - Unordered sets</p>
</div>
<div id="toc" class="section"><h2><a name="toc">Table Of Contents</a></h2>
<ul class="toc">
<li class="section"><a href="#toc">Table Of Contents</a></li>
<li class="section"><a href="#synopsis">Synopsis</a></li>
<li class="section"><a href="#section1">Description</a></li>
<li class="section"><a href="#section2">ROUTINES</a></li>
<li class="section"><a href="#copyright">Copyright</a></li>
</ul>
</div>
<div id="synopsis" class="section"><h2><a name="synopsis">Synopsis</a></h2>
<div class="synopsis">
<ul class="syntax">
<li><a href="#1"><b class="cmd">call set_create( dataset )</b></a></li>
<li><a href="#2"><b class="cmd">call set_destroy( dataset )</b></a></li>
<li><a href="#3"><b class="cmd">size = set_size( dataset )</b></a></li>
<li><a href="#4"><b class="cmd">call set_add( dataset, elem )</b></a></li>
<li><a href="#5"><b class="cmd">call set_delete_element( dataset, elem )</b></a></li>
<li><a href="#6"><b class="cmd">has = set_haselement( dataset, elem )</b></a></li>
<li><a href="#7"><b class="cmd">has = elem .elementof. dataset</b></a></li>
<li><a href="#8"><b class="cmd">equal = set_equal( set1, set2 )</b></a></li>
<li><a href="#9"><b class="cmd">equal = set1 .eq. set2</b></a></li>
<li><a href="#10"><b class="cmd">notequal = set_notequal( set1, set2 )</b></a></li>
<li><a href="#11"><b class="cmd">notequal = set1 .ne. set2</b></a></li>
<li><a href="#12"><b class="cmd">has = set_hassubset( dataset, subset )</b></a></li>
<li><a href="#13"><b class="cmd">has = subset .subsetof. dataset</b></a></li>
<li><a href="#14"><b class="cmd">newset = set_union( set1, set2 )</b></a></li>
<li><a href="#15"><b class="cmd">newset = set1 .union. set2</b></a></li>
<li><a href="#16"><b class="cmd">newset = set_intersection( set1, set2 )</b></a></li>
<li><a href="#17"><b class="cmd">newset = set1 .intersect. set2</b></a></li>
<li><a href="#18"><b class="cmd">newset = set_exclusion( set1, set2 )</b></a></li>
<li><a href="#19"><b class="cmd">newset = set1 .intersect. set2</b></a></li>
</ul>
</div>
</div>
<div id="section1" class="section"><h2><a name="section1">Description</a></h2>
<p>The <em>sets.f90</em> source file allows you to implement
<em>unordered sets</em> of any (derived) type without having to
edit the supplied source code. To this end a simple technique is used,
which is best illustrated by an example:</p>
<pre class="example">
!
! The data that will be stored in the sets
!
type MYDATA
    integer :: value
end type MYDATA
!
! As derived types are compared, we need to define
! how to compare them
!
interface operator(.eq.)
    module procedure mydata_isequal
end interface
contains
logical function mydata_isequal( v1, v2 )
    type(MYDATA), intent(in) :: v1
    type(MYDATA), intent(in) :: v2
    mydata_isequal = v1%value .eq. v2%value
end function mydata_isequal
end module MYDATA_MODULE
module MYDATA_SET_STRUCTS
    use MYDATA_MODULE, SET_DATA =&gt; MYDATA
    include &quot;data_for_sets.f90&quot;
end module MYDATA_SET_STRUCTS
module MYDATA_SETS
    use MYDATA_SET_STRUCTS
    include &quot;sets.f90&quot;
end module MYDATA_SETS
</pre>
<p>The above code defines a module <em>MYDATA_MODULE</em> with the derived
type that is to be stored in the sets. The name of that derived
type can be anything.</p>
<p>It also defines a module <em>MYDATA_SET_STRUCTS</em> which prepares the
underlying data structure. The reason for this two-layer process is that
you need to be able to define the name of the modules that are involved
yourself. (Otherwise it would be impossible to use two or more
<em>sets</em> holding different types of data in one program.</p>
<p>It finally defines a module <em>MYDATA_SETS</em> which will be the
module that holds the functionality to use unordered sets:</p>
<ul class="itemized">
<li><p>The module <em>MYDATA_MODULE</em> is <em>used</em>, but the derived type
<em>MYDATA</em> is renamed to the (fixed) name <em>SET_DATA</em>. (This
is the name used in the generic source file.)</p></li>
<li><p>The source code for the actual routines is simply included via the
INCLUDE statement.</p></li>
<li><p>Nothing more is required, we can close the source text for the module.</p></li>
</ul>
<p>To use a single type of sets in a program, we can just use the
MYDATA_SETS module. If you need more than one type of data in sets,
then apply the same renaming trick on using the specific set
modules.</p>
<p>In fact the example in the source file &quot;two_lists.f90&quot; shows the general
technique of how to accomplish this.</p>
</div>
<div id="section2" class="section"><h2><a name="section2">ROUTINES</a></h2>
<p>The source file <em>sets.f90</em> provides the following
routines:</p>
<dl class="definitions">
<dt><a name="1"><b class="cmd">call set_create( dataset )</b></a></dt>
<dd><p>Create a new empty set.</p>
<dl class="arguments">
<dt>type(SET) <i class="arg">dataset</i></dt>
<dd><p>The variable that will be used for accessing the set</p></dd>
</dl></dd>
<dt><a name="2"><b class="cmd">call set_destroy( dataset )</b></a></dt>
<dd><p>Destroy the set. All elements contained in it will be destroyed as
well.</p>
<dl class="arguments">
<dt>type(SET) <i class="arg">dataset</i></dt>
<dd><p>The set to be destroyed</p></dd>
</dl></dd>
<dt><a name="3"><b class="cmd">size = set_size( dataset )</b></a></dt>
<dd><p>Function to return the number of elements in the set.</p>
<dl class="arguments">
<dt>type(SET) <i class="arg">dataset</i></dt>
<dd><p>The set in question</p></dd>
</dl></dd>
<dt><a name="4"><b class="cmd">call set_add( dataset, elem )</b></a></dt>
<dd><p>Insert a new element in the set. If the element is already present,
nothing is done.</p>
<dl class="arguments">
<dt>type(SET) <i class="arg">dataset</i></dt>
<dd><p>The dataset to add the element to.</p></dd>
<dt>type(SET_DATA), intent(in) <i class="arg">elem</i></dt>
<dd><p>The element to be stored</p></dd>
</dl></dd>
<dt><a name="5"><b class="cmd">call set_delete_element( dataset, elem )</b></a></dt>
<dd><p>Delete the given element from the set.</p>
<dl class="arguments">
<dt>type(SET) <i class="arg">dataset</i></dt>
<dd><p>The list in question</p></dd>
<dt>type(SET_DATA) <i class="arg">elem</i></dt>
<dd><p>The element to be deleted</p></dd>
</dl></dd>
<dt><a name="6"><b class="cmd">has = set_haselement( dataset, elem )</b></a></dt>
<dd><p>Returns whether or not the given element is in the set.</p>
<dl class="arguments">
<dt>type(SET) <i class="arg">dataset</i></dt>
<dd><p>The set in question</p></dd>
<dt>type(SET_DATA) <i class="arg">elem</i></dt>
<dd><p>The element to be checked</p></dd>
</dl></dd>
<dt><a name="7"><b class="cmd">has = elem .elementof. dataset</b></a></dt>
<dd><p>Returns whether or not the given element is in the set.
(The operator version)</p>
<dl class="arguments">
<dt>type(SET) <i class="arg">dataset</i></dt>
<dd><p>The set in question</p></dd>
<dt>type(SET_DATA) <i class="arg">elem</i></dt>
<dd><p>The element to be checked</p></dd>
</dl></dd>
<dt><a name="8"><b class="cmd">equal = set_equal( set1, set2 )</b></a></dt>
<dd><p>Returns whether or not the two sets contain the same elements.</p>
<dl class="arguments">
<dt>type(SET) <i class="arg">set1</i></dt>
<dd><p>The first set</p></dd>
<dt>type(SET) <i class="arg">set2</i></dt>
<dd><p>The second set</p></dd>
</dl></dd>
<dt><a name="9"><b class="cmd">equal = set1 .eq. set2</b></a></dt>
<dd><p>Returns whether or not the two sets contain the same elements.
(The operator version)</p></dd>
<dt><a name="10"><b class="cmd">notequal = set_notequal( set1, set2 )</b></a></dt>
<dd><p>Returns whether or not the two sets do not contain the same elements.
(The operator version)</p>
<dl class="arguments">
<dt>type(SET) <i class="arg">set1</i></dt>
<dd><p>The first set</p></dd>
<dt>type(SET) <i class="arg">set2</i></dt>
<dd><p>The second set</p></dd>
</dl></dd>
<dt><a name="11"><b class="cmd">notequal = set1 .ne. set2</b></a></dt>
<dd><p>Returns whether or not the two sets do not contain the same elements.
(The operator version)</p></dd>
<dt><a name="12"><b class="cmd">has = set_hassubset( dataset, subset )</b></a></dt>
<dd><p>Returns whether or not one set is contained in the other set.</p>
<dl class="arguments">
<dt>type(SET) <i class="arg">dataset</i></dt>
<dd><p>The set that may hold the second one</p></dd>
<dt>type(SET) <i class="arg">subset</i></dt>
<dd><p>The set that may be a subset of the fist</p></dd>
</dl></dd>
<dt><a name="13"><b class="cmd">has = subset .subsetof. dataset</b></a></dt>
<dd><p>Returns whether or not one set is contained in the other set.
(The operator version)</p>
<dl class="arguments">
<dt>type(SET) <i class="arg">subset</i></dt>
<dd><p>The set that may be a subset of the other</p></dd>
<dt>type(SET) <i class="arg">dataset</i></dt>
<dd><p>The set that may hold the first one</p></dd>
</dl></dd>
<dt><a name="14"><b class="cmd">newset = set_union( set1, set2 )</b></a></dt>
<dd><p>Returns the union of two sets.</p>
<dl class="arguments">
<dt>type(SET) <i class="arg">set1</i></dt>
<dd><p>The first set</p></dd>
<dt>type(SET) <i class="arg">set2</i></dt>
<dd><p>The second set</p></dd>
</dl></dd>
<dt><a name="15"><b class="cmd">newset = set1 .union. set2</b></a></dt>
<dd><p>Returns the union of two sets - operator version.</p></dd>
<dt><a name="16"><b class="cmd">newset = set_intersection( set1, set2 )</b></a></dt>
<dd><p>Returns the intersection of two sets.</p>
<dl class="arguments">
<dt>type(SET) <i class="arg">set1</i></dt>
<dd><p>The first set</p></dd>
<dt>type(SET) <i class="arg">set2</i></dt>
<dd><p>The second set</p></dd>
</dl></dd>
<dt><a name="17"><b class="cmd">newset = set1 .intersect. set2</b></a></dt>
<dd><p>Returns the intersection of two sets - operator version.</p></dd>
<dt><a name="18"><b class="cmd">newset = set_exclusion( set1, set2 )</b></a></dt>
<dd><p>Returns a copy of the first set with the elements of the second set
excluded.</p>
<dl class="arguments">
<dt>type(SET) <i class="arg">set1</i></dt>
<dd><p>The first set</p></dd>
<dt>type(SET) <i class="arg">set2</i></dt>
<dd><p>The second set</p></dd>
</dl></dd>
<dt><a name="19"><b class="cmd">newset = set1 .intersect. set2</b></a></dt>
<dd><p>Returns a copy of the first set with the elements of the second set
excluded - operator version.</p></dd>
</dl>
<p>Notes:</p>
<ul class="itemized">
<li><p>The sets can only store data of the same derived type. In that sense
the code is not generic.</p></li>
<li><p>Currently, the sets can only store derived types that do not require
an explicit destruction. If you want to store a derived type with
pointers to allocated memory, you can do that however, by supplying an
assignment operator. This would lead to a memory leak though. It is best
to wait for the next version which will allow such derived types to be
stored.</p></li>
</ul>
</div>
<div id="copyright" class="section"><h2><a name="copyright">Copyright</a></h2>
<p>Copyright &copy; 2006 Arjen Markus &lt;arjenmarkus@sourceforge.net&gt;</p>
</div>
</div></body></html>